#pragma once
#ifndef DATACENTER_H
#define DATACENTER_H

#include "../network/netclient.h"
#include "data.h"
#include <QDir>
#include <QJsonDocument>
#include <QJsonObject>
#include <QObject>
#include <QStandardPaths>

// 前置声明解决循环包含问题
namespace network
{
class NetClient;
}

namespace model
{
class DataCenter : public QObject
{
    Q_OBJECT
  public:
    static DataCenter *getInstance();
    ~DataCenter();

    void initDataFile();
    void saveDataFile();
    void loadDataFile();

    void ping() { _netClient.ping(); }

    void initWebsocket();
    void getMyselfAsync();
    UserInfo *getMyself();
    void resetMyself(std::shared_ptr<MicroIMS::GetUserInfoRsp> resp);

    void getFriendListAsync();
    QList<UserInfo> *getFriendList();
    void resetFriendList(std::shared_ptr<MicroIMS::GetFriendListRsp> resp);

    void getChatSessionListAsync();
    QList<ChatSessionInfo> *getChatSessionList();
    void resetChatSessionList(std::shared_ptr<MicroIMS::GetChatSessionListRsp> resp);

    void getApplyListAsync();
    QList<UserInfo> *getApplyList();
    void resetApplyList(std::shared_ptr<MicroIMS::GetPendingFriendEventListRsp> resp);

    void getRecentMessageListAsync(const QString &chatSessionId, bool updateUI);
    QList<Message> *getRecentMessageList(const QString &chatSessionId);
    void resetRecentMessageList(const QString &chatSessionId, std::shared_ptr<MicroIMS::GetRecentMsgRsp> resp);

    const QString &getLoginSessionId() { return _loginSessionId; }

    ChatSessionInfo *findChatSessionById(const QString &chatSessionId);
    ChatSessionInfo *findChatSessionByUserId(const QString &userId);
    void setCurrentChatSessionId(const QString &chatSessionId);
    QString &getCurrentChatSessionId();
    void topChatSessionInfo(const ChatSessionInfo &chatSessionInfo);

    void sendTextMessageAsync(const QString &chatSessionId, const QString &content);
    void addMessage(const Message &message);

    void clearUnread(const QString &chatSessionId);
    void addUnread(const QString &chatSessionId);
    int getUnread(const QString &chatSessionId);

    void changeNicknameAsync(const QString &nickname);
    void resetNickname(const QString &nickname);

    void changeDescriptionAsync(const QString &desc);
    void resetDescription(const QString &desc);

    void getVerifyCodeAsync(const QString &phone);
    const QString &getVerifyCodeId();
    void resetVerifyCodeId(const QString &verifyCodeId);
    void changePhoneAsync(const QString &phone, const QString &verifyCodeId, const QString &verifyCode);
    void resetPhone(const QString &phone);

    void changeAvatarAsync(const QByteArray &imageBytes);
    void resetAvatar(const QByteArray &avatar);

    UserInfo *findFriendById(const QString &userId);

    void deleteFriendAsync(const QString &userId);
    void removeFriend(const QString &userId);

    void addFriendApplyAsync(const QString &userId);

  private:
    DataCenter();
    static DataCenter *instance;

  private:
    // 当前客户端登录到服务器对应的登录会话 id
    QString _loginSessionId = "";

    // 当前用户信息
    UserInfo *_myself = nullptr;

    // 好友列表
    QList<UserInfo> *_friendList = nullptr;

    // 会话列表
    QList<ChatSessionInfo> *_chatSessionList = nullptr;

    // 当前选中的会话是哪一个
    QString _currentChatSessionId = "";

    // 记录每个会话中的成员（针对群聊），key -- chatSessionId ; value -- 成员列表
    QHash<QString, QList<UserInfo>> *_memberList = nullptr;

    // 待处理的好友申请
    QList<UserInfo> *_applyList = nullptr;

    // 存储每个会话的最近消息列表，key -- chatSessionId ; value -- 消息列表
    QHash<QString, QList<Message>> *_recentMessages = nullptr;

    // 存储每个会话的未读消息，key -- chatSessionId ; value -- 未读消息个数
    QHash<QString, int> *_unreadMessageCount = nullptr;

    // 用户的好友搜索结果
    QList<UserInfo> *_searchUserResult = nullptr;

    // 历史消息搜索结果
    QList<Message> *_searchMessageResult = nullptr;

    // 短信验证码的验证 id
    QString _currentVerifyCodeId = "";

    network::NetClient _netClient;

  signals:
    void getMyselfDone();
    void getFriendListDone();
    void getChatSessionListDone();
    void getApplyListDone();
    void getRecentMessageListDone(const QString &chatSessionId);
    void getRecentMessageListDoneNoUI(const QString &chatSessionId);
    void sendMessageDone(MessageType messageType, const QByteArray &content, const QString &extraInfo);
    void updateLastMessage(const QString &lastMessage);
    void receiveMessageDone(const Message &lastMessage);
    void changeNicknameDone();
    void changeDescriptionDone();
    void getVerifyCodeDone();
    void changePhoneDone();
    void changeAvatarDone();
    void deleteFriendDone();
    void clearCurrentSession();
    void addFriendApplyDone();
    void receiveFriendApplyDone();
};
} // namespace model
#endif // DATACENTER_H
